(function(context) {
    var tools = {};
    tools.fmtDate = function(date, format) {
        var o = {
            "M+": date.getMonth() + 1,
            "d+": date.getDate(),
            "h+": date.getHours(),
            "m+": date.getMinutes(),
            "s+": date.getSeconds(),
            "q+": Math.floor((date.getMonth() + 3) / 3),
            "S": date.getMilliseconds()
        };
        if (/(y+)/.test(format)) {
            format = format.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length))
        }
        for (var k in o) {
            if (new RegExp("(" + k + ")").test(format)) {
                format = format.replace(RegExp.$1, RegExp.$1.length == 1 ? o[k] : ("00" + o[k]).substr(("" + o[k]).length))
            }
        }
        return format
    };
    tools.getVal = function($data, exp) {
        return new Function("$data", "return $data." + exp)($data)
    };
    var xView = {
        tools: tools
    };
    xView.tempModel = {};
    xView.setModel = function(group, model) {
        group.find("[x-view]").each(function(i, e) {
            var name = $(e).attr("x-view");
            var widget = resolveType(name, e);
            if (!widget) {
                console.warn(e);
                return
            }
            widget.setView(e, tools.getVal(model, $(e).attr("x-name")), $(e).attr("data-view"))
        })
    };
    xView.getModel = function(group) {
        var ret = {};
        group.find("[x-view]").each(function(i, e) {
            var name = $(e).attr("x-view");
            new Widget(e,)
            var t = resolveType(name, e);
            if (!t) {
                console.warn(e);
                return;
            }
            ret[$(e).attr("x-name")] = t.getData(e, $(e).attr("data-view"));
        })
    };
    xView.setForm = function(form, model) {
        var $form = $(form);
        var handered = {};
        $form.find("input,select,textarea").each(function(i, ee) {
            var e = ee;
            if (!e.name) {
                return
            }
            if (e.tagName == "INPUT" && e.type == "radio") {
                if (handered["input-radio-" + e.name]) {
                    return
                }
                handered["input-radio-" + e.name] = 1;
                e = $form.find("input[type=radio][name=" + e.name + "]").toArray()
            }
            if (e.tagName == "INPUT" && e.type == "checkbox") {
                if (handered["input-checkbox-" + e.name]) {
                    return
                }
                handered["input-checkbox-" + e.name] = 1;
                e = $form.find("input[type=checkbox][name=" + e.name + "]").toArray()
            }
            var widget = resolveFormType(e);
            if (!widget) {
                console.warn(e);
                return
            }
            var dview;
            if (Array.isArray(e)) {
                $.each(e, function(i, e2) {
                    if ($(e2).attr("data-view")) {
                        dview = $(e2).attr("data-view")
                    }
                })
            } else {
                dview = $(e).attr("data-view")
            }
            widget.setView(e, tools.getVal(model, Array.isArray(e) ? e[0].name : e.name), dview)
        })
    };
    xView.getForm = function(form) {
        var o = {};
        var a = $(form).serializeArray();
        $.each(a, function() {
            if (o[this.name]) {
                if (!o[this.name].push) {
                    o[this.name] = [o[this.name]]
                }
                o[this.name].push(this.value || "")
            } else {
                o[this.name] = this.value || ""
            }
        });
        return o
    };
    xView.val = function(ee,val) {
        var widget = resolveType($(ee).attr("x-view"),ee);
        if (!widget) {
            console.warn(e);
            return
        }
        if(typeof(val)=="undefined")return widget.getData();
        widget.setView(ee,val,$(ee).attr("data-view"))

    };

    //语法 控件名(key)
    parseXView = function(exp){
        var i = exp.indexOf("(")
        var key = exp.substring(0,i).trim();
        var param = exp.substring(i,exp.length).replace(/\(|\)|\s+/g,"").split(",")
        return {key:key,param:param};

    }

    resolveType = function(key, e) {
        if (!key) {
            return resolveDefType(e)
        }
        return xView.widget[key]
    };
    resolveDefType = function(e) {
        switch (e.tagName) {
            case "INPUT":
                return xView.widget["input"];
                break;
            default:
                return xView.widget["div"];
                break
        }
    };
    resolveFormType = function(e) {
        var tagName = Array.isArray(e) ? e[0].tagName : e.tagName;
        if (tagName == "INPUT") {
            var type = Array.isArray(e) ? e[0].type : e.type;
            switch (type) {
                case "radio":
                    return xView.widget["input-radio"];
                case "checkbox":
                    return xView.widget["input-checkbox"];
                default:
                    return xView.widget["input"]
            }
        } else {
            if (tagName == "SELECT") {
                return xView.widget["select"]
            } else {
                if (tagName == "TEXTAREA") {
                    return xView.widget["textarea"]
                }
            }
        }
    };

    xView.register = function(name,widget){
        if(xView.widget[name])
            throw "组件"+name+"已经注册";
        xView.widget[name] = widget;


    }

    xView.converter = {};
    xView.converter['default'] = {
        cfg:null,
        input:function(v){
            return v;
        },
        output:function(v){
            return v;
        }
    }

    xView.converter['time'] = {
        cfg:null,
        input:function(v){
            return xView.tools.fmtDate(new Date(new Number(v)), this.conf.view);;
        },
        output:function(v){
            return v;
        }
    }

    xView.widget = {};
    xView.widget["select"] = xView.widget["input"] = {
        setView: function(val) {
            $(this.e).val(val)
        },
        getData: function(e) {
            return $(e).val()
        }
    };
    xView.widget["input-radio"] = {
        setView: function(val) {
            $.each(ee, function(i, e) {
                if (val == e.value) {
                    $(e).attr("checked", "checked")
                }
            })
        },
        getData: function(e) {
            return ""
        }
    };
    xView.widget["input-checkbox"] = {
        setView: function(ee, vals, fmt) {
            var config = eval("(" + fmt + ")");
            if(!Array.isArray(vals))vals = [vals];
            for (var i = 0; i < vals.length; i++) {
                var val = xView.format(vals[i], config);
                $.each(ee, function(i, e) {
                    if (val == e.value) {
                        $(e).attr("checked", "checked")
                    }
                })
            }

        },
        getData: function(e) {
            return ""
        }
    };
    xView.widget["textarea"] = xView.widget["div"] = {
        setView: function(e, val, fmt) {
            var config = eval("(" + fmt + ")");
            val = xView.format(val, config);
            $(e).html(val)
        },
        getData: function(e) {
            return $(e).html()
        }
    };
    xView.format = function(val, conf) {
        if (!conf) {
            return val
        }
        switch (conf.data) {
            case "time":
                if (isNaN(val)) {
                    return
                }
                return xView.tools.fmtDate(new Date(new Number(val)), conf.view);
                break;
            case "enum":
                return conf.view[val];
                break;
            default:
                return val;
                break;
        }
    };





    function Widget(e,opt){
        this.e = e;
        this.key = opt.key;
        this.dataView = opt.dataView;
        this.name = opt.name;
        this.handle = opt.handle;
    }


    context.xView = xView
})(window);
